package ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.utils;

import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.enums.SaveContextActionEnum;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.model.SaveContext;
import ace.cmp.data.spring.data.jdbc.querydsl.rsql.core.model.SaveListContext;
import ace.cmp.util.AceStreamUtils;
import java.util.List;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;

/**
 * .
 *
 * @author Caspar
 *
 */
@AllArgsConstructor
public class SaveContextUtils {

  public static <T> SaveListContext<T> toSaveListContext(List<SaveContext<T>> saveContextList) {
    return SaveListContext.<T>builder()
        .data(saveContextList)
        .build();
  }

  public static <T> SaveListContext<T> mergeSaveListContext(List<SaveListContext<T>> saveListContexts) {
    List<SaveContext<T>> saveContexts = AceStreamUtils.ofNullable(saveListContexts)
        .map(SaveListContext::getData)
        .flatMap(List::stream)
        .collect(Collectors.toList());

    return toSaveListContext(saveContexts);
  }

  public static <T> SaveContext<T> empty() {
    return SaveContext.<T>builder()
        .data(null)
        .action(SaveContextActionEnum.NONE)
        .build();
  }


  public static <T> SaveListContext<T> of(List<SaveContext<T>> saveContextList) {
    return SaveContextUtils.toSaveListContext(saveContextList);
  }

  /**
   * 创建保存操作上下文.
   *
   * @param entity 实体
   * @param isNew 是否新增
   * @return 保存操作上下文
   */
  public static <TEntity> SaveContext<TEntity> of(TEntity entity, boolean isNew) {
    return SaveContext.<TEntity>builder()
        .data(entity)
        .action(isNewOrModify(isNew))
        .build();
  }

  /**
   * 创建新增操作上下文.
   *
   * @param entity 实体
   * @return 新增操作上下文
   */
  public static <TEntity> SaveContext<TEntity> ofNew(TEntity entity) {
    return of(entity, true);
  }

  /**
   * 创建修改操作上下文.
   *
   * @param entity 实体
   * @return 修改操作上下文
   */
  public static <TEntity> SaveContext<TEntity> ofModify(TEntity entity) {
    return of(entity, false);
  }

  /**
   * 创建保存操作上下文.
   *
   * @param entities 实体
   * @param isNew 是否新增
   * @return 保存操作上下文
   */
  public static <TEntity> SaveListContext<TEntity> of(List<TEntity> entities, boolean isNew) {
    List<SaveContext<TEntity>> saveContexts = AceStreamUtils.ofNullable(entities)
        .map(entity -> SaveContextUtils.of(entity, isNew))
        .collect(Collectors.toList());

    return SaveListContext.<TEntity>builder()
        .data(saveContexts)
        .build();
  }

  /**
   * 创建新增操作上下文.
   *
   * @param entities 实体
   * @return 新增操作上下文
   */
  public static <TEntity> SaveListContext<TEntity> ofNew(List<TEntity> entities) {
    return SaveContextUtils.of(entities, true);
  }

  /**
   * 创建修改操作上下文.
   *
   * @param entities 实体
   * @return 修改操作上下文
   */
  public static <TEntity> SaveListContext<TEntity> ofModify(List<TEntity> entities) {
    return SaveContextUtils.of(entities, false);
  }


  private static SaveContextActionEnum isNewOrModify(boolean isNew) {
    return isNew ? SaveContextActionEnum.ADD : SaveContextActionEnum.MODIFY;
  }
}
